﻿#region << 文 件 说 明 >>

/*----------------------------------------------------------------
// 文件名称：VPagination
// 创 建 者：杨程
// 创建时间：2021/12/8 9:50:21
// 文件版本：V1.0.0
// ===============================================================
// 功能描述：
//
//
//----------------------------------------------------------------*/

#endregion



namespace Vampirewal.Core.WPF.Theme;

[TemplatePart(Name = "PART_ComboBox", Type = typeof(ComboBox))]
[TemplatePart(Name = "PART_ButtonFirstPage", Type = typeof(Button))]
[TemplatePart(Name = "PART_ButtonPrePage", Type = typeof(Button))]
[TemplatePart(Name = "PART_ListBoxPages", Type = typeof(ListBox))]
[TemplatePart(Name = "PART_ButtonNextPage", Type = typeof(Button))]
[TemplatePart(Name = "PART_ButtonLastPage", Type = typeof(Button))]
[TemplatePart(Name = "PART_PageInfo", Type = typeof(Panel))]
public class VPagination : Control
{
    public static event PropertyChangedEventHandler PropertyChanged;

    #region 是否显示每页数据量选择控件

    /// <summary>
    /// 是否显示每页数据量选择控件
    /// </summary>
    public bool IsShowPageDataCountSelector
    {
        get { return (bool)GetValue(IsShowPageDataCountSelectorProperty); }
        set { SetValue(IsShowPageDataCountSelectorProperty, value); }
    }

    /// <summary>
    /// 是否显示每页数据量选择控件
    /// </summary>
    public static readonly DependencyProperty IsShowPageDataCountSelectorProperty =
        DependencyProperty.Register("IsShowPageDataCountSelector", typeof(bool), typeof(VPagination), new PropertyMetadata(true, null));

    #endregion

    #region 可选择的每页显示的数据条数集合

    /// <summary>
    /// 可选择的每页显示的数据条数集合
    /// </summary>
    public ObservableCollection<int> PageDataCountCollection
    {
        get { return (ObservableCollection<int>)GetValue(PageDataCountCollectionProperty); }
        set { SetValue(PageDataCountCollectionProperty, value); }
    }

    /// <summary>
    /// 可选择的每页显示的数据条数集合
    /// </summary>
    public static readonly DependencyProperty PageDataCountCollectionProperty = DependencyProperty.Register("PageDataCountCollection", typeof(ObservableCollection<int>), typeof(VPagination),
        new PropertyMetadata(new ObservableCollection<int> { 20, 30, 50 }, null));

    #endregion

    #region 每页最多显示的数据条数

    /// <summary>
    /// 每页最多显示的数据条数
    /// </summary>
    public int PageDataCount
    {
        get { return (int)GetValue(PageDataCountProperty); }
        set { SetValue(PageDataCountProperty, value); }
    }

    /// <summary>
    /// 每页最多显示的数据条数
    /// </summary>
    public static readonly DependencyProperty PageDataCountProperty = DependencyProperty.Register("PageDataCount", typeof(int), typeof(VPagination),
        new PropertyMetadata(20, OnPageDataCountPropertyChanged));

    /// <summary>
    /// 每页显示的最大数据量发生改变时的回调方法
    /// </summary>
    /// <param name="d"></param>
    /// <param name="e"></param>
    private static void OnPageDataCountPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        VPagination pagination = d as VPagination;
        if (pagination == null)
        {
            return;
        }

        pagination.InitData();
    }

    #endregion

    #region 当前显示的可供选择的分页号集合

    /// <summary>
    /// 当前显示的可供选择的分页号集合
    /// </summary>
    public ObservableCollection<int> ShowingPageNumberCollection
    {
        get { return (ObservableCollection<int>)GetValue(ShowingPageNumberCollectionProperty); }
        set { SetValue(ShowingPageNumberCollectionProperty, value); }
    }

    /// <summary>
    /// 当前显示的可供选择的分页号集合
    /// </summary>
    public static readonly DependencyProperty ShowingPageNumberCollectionProperty = DependencyProperty.Register("ShowingPageNumberCollection", typeof(ObservableCollection<int>), typeof(VPagination),
        new PropertyMetadata(null, null));

    #endregion

    #region 当前选择的页数

    /// <summary>
    /// 当前选择的页数
    /// </summary>
    public int CurrentPageNumber
    {
        get { return (int)GetValue(CurrentPageNumberProperty); }
        set { SetValue(CurrentPageNumberProperty, value); }
    }

    /// <summary>
    /// 当前选择的页数
    /// </summary>
    public static readonly DependencyProperty CurrentPageNumberProperty = DependencyProperty.Register("CurrentPageNumber", typeof(int), typeof(VPagination),
        new PropertyMetadata(1, OnCurrentPageNumberChanged));

    /// <summary>
    /// 当前选择的页数发生改变时的回调方法
    /// </summary>
    /// <param name="d"></param>
    /// <param name="e"></param>
    private static void OnCurrentPageNumberChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        VPagination pagination = d as VPagination;
        if (pagination == null)
        {
            return;
        }

        if (pagination._lstShowingPage != null)
        {
            pagination._lstShowingPage.SelectedItem = e.NewValue;
        }

        pagination.SetBtnEnable();
        //PropertyChanged(d, new PropertyChangedEventArgs(e.Property.Name));
        PropertyChanged?.Invoke(d, new PropertyChangedEventArgs(e.Property.Name));
    }

    #endregion

    #region 是否显示分页信息

    /// <summary>
    /// 是否显示分页信息
    /// </summary>
    public bool IsShowPageInfo
    {
        get { return (bool)GetValue(IsShowPageInfoProperty); }
        set { SetValue(IsShowPageInfoProperty, value); }
    }

    /// <summary>
    /// 是否显示分页信息
    /// </summary>
    public static readonly DependencyProperty IsShowPageInfoProperty = DependencyProperty.Register("IsShowPageInfo", typeof(bool), typeof(VPagination),
        new PropertyMetadata(true, null));

    #endregion

    #region 总的数据量

    /// <summary>
    /// 总的数据量
    /// </summary>
    public int TotalDataCount
    {
        get { return (int)GetValue(TotalDataCountProperty); }
        set { SetValue(TotalDataCountProperty, value); }
    }

    /// <summary>
    /// 总的数据量
    /// </summary>
    public static readonly DependencyProperty TotalDataCountProperty = DependencyProperty.Register("TotalDataCount", typeof(int), typeof(VPagination),
        new PropertyMetadata(0, null));

    #endregion

    #region 当前页显示的数据条数

    /// <summary>
    /// 当前页显示的数据条数
    /// </summary>
    public int CurrentPageDataCount
    {
        get { return (int)GetValue(CurrentPageDataCountProperty); }
        set { SetValue(CurrentPageDataCountProperty, value); }
    }

    /// <summary>
    /// 当前页显示的数据条数
    /// </summary>
    public static readonly DependencyProperty CurrentPageDataCountProperty = DependencyProperty.Register("CurrentPageDataCount", typeof(int), typeof(VPagination),
        new PropertyMetadata(0, null));

    #endregion

    #region 总页数

    /// <summary>
    /// 总页数
    /// </summary>
    public int TotalPageCount
    {
        get { return (int)GetValue(TotalPageCountProperty); }
        set { SetValue(TotalPageCountProperty, value); }
    }

    /// <summary>
    /// 总页数
    /// </summary>
    public static readonly DependencyProperty TotalPageCountProperty = DependencyProperty.Register("TotalPageCount", typeof(int), typeof(VPagination),
        new PropertyMetadata(1, null));

    #endregion

    #region 当前显示页的数据起始编号

    /// <summary>
    /// 当前显示页的数据起始编号
    /// </summary>
    public int ShowingPageDataStartNumber
    {
        get { return (int)GetValue(ShowingPageDataStartNumberProperty); }
        set { SetValue(ShowingPageDataStartNumberProperty, value); }
    }

    /// <summary>
    /// 当前显示页的数据起始编号
    /// </summary>
    public static readonly DependencyProperty ShowingPageDataStartNumberProperty = DependencyProperty.Register("ShowingPageDataStartNumber", typeof(int), typeof(VPagination),
        new PropertyMetadata(0, null));

    #endregion

    #region 当前显示页的数据结束编号

    /// <summary>
    /// 当前显示页的数据结束编号
    /// </summary>
    public int ShowingPageDataEndNumber
    {
        get { return (int)GetValue(ShowingPageDataEndNumberProperty); }
        set { SetValue(ShowingPageDataEndNumberProperty, value); }
    }

    /// <summary>
    /// 当前显示页的数据结束编号
    /// </summary>
    public static readonly DependencyProperty ShowingPageDataEndNumberProperty = DependencyProperty.Register("ShowingPageDataEndNumber", typeof(int), typeof(VPagination),
        new PropertyMetadata(0, null));

    #endregion

    #region 显示的可选择页的最大数量

    /// <summary>
    /// 显示的可选择页的最大数量
    /// </summary>
    public int MaxShownPageCount
    {
        get { return (int)GetValue(MaxShownPageCountProperty); }
        set { SetValue(MaxShownPageCountProperty, value); }
    }

    /// <summary>
    /// 显示的可选择页的最大数量
    /// </summary>
    public static readonly DependencyProperty MaxShownPageCountProperty = DependencyProperty.Register("MaxShownPageCount", typeof(int), typeof(VPagination),
        new PropertyMetadata(7, null));

    #endregion

    #region 选中页的背景色

    /// <summary>
    /// 选中页的背景色
    /// </summary>
    public Brush SelectedPageBackground
    {
        get { return (Brush)GetValue(MaxShownPageCountProperty); }
        set { SetValue(MaxShownPageCountProperty, value); }
    }

    /// <summary>
    /// 选中页的背景色
    /// </summary>
    public static readonly DependencyProperty SelectedPageBackgroundProperty = DependencyProperty.Register("SelectedPageBackground", typeof(Brush), typeof(VPagination),
        new PropertyMetadata(new SolidColorBrush(Colors.Red), null));

    #endregion

    #region 未选择的页码的背景色

    /// <summary>
    /// 未选择的页码的背景色
    /// </summary>
    public Brush PageSelectorBackground
    {
        get { return (Brush)GetValue(PageSelectorBackgroundProperty); }
        set { SetValue(PageSelectorBackgroundProperty, value); }
    }

    /// <summary>
    /// 未选择的页码的背景色
    /// </summary>
    public static readonly DependencyProperty PageSelectorBackgroundProperty = DependencyProperty.Register("PageSelectorBackground", typeof(Brush), typeof(VPagination),
        new PropertyMetadata(null, null));

    #endregion

    //private ResourceDictionary res
    //{
    //    get
    //    {
    //        return new ResourceDictionary() { Source = new Uri("pack://application:,,,/Vampirewal.Core.WPF.Theme;component/Theme.xaml", UriKind.RelativeOrAbsolute) };
    //    }
    //}

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        //var VPaginationStyle = res["VPaginationStyle"] as Style;

        //this.Style = VPaginationStyle;

        //初始化控件
        InitControls();

        //初始化数据
        ShowingPageNumberCollection = new ObservableCollection<int>();
        InitData();
    }

    private ComboBox _cbbPageDataCount { get; set; }

    private ListBox _lstShowingPage { get; set; }

    private Button _btnFirstPage { get; set; }

    private Button _btnPrePage { get; set; }

    private Button _btnNextPage { get; set; }

    private Button _btnLastPage { get; set; }

    private bool _isIgnoreListBoxSelectionChanged { get; set; }

    private static object _lock = new object();

    public VPagination()
    {
    }

    static VPagination()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(VPagination), new FrameworkPropertyMetadata(typeof(VPagination)));
    }

    /// <summary>
    /// 初始化控件
    /// </summary>
    private void InitControls()
    {
        _cbbPageDataCount = this.Template.FindName("PART_ComboBox", this) as ComboBox;
        if (_cbbPageDataCount != null)
        {
            _cbbPageDataCount.SelectionChanged += _cbbPageDataCount_SelectionChanged;
        }

        _lstShowingPage = GetTemplateChild("PART_ListBoxPages") as ListBox;
        if (_lstShowingPage != null)
        {
            _lstShowingPage.SelectionChanged += _lstShowingPage_SelectionChanged;
        }

        _btnFirstPage = GetTemplateChild("PART_ButtonFirstPage") as Button;
        if (_btnFirstPage != null)
        {
            _btnFirstPage.Click += _btnFirstPage_Click;
        }

        _btnPrePage = GetTemplateChild("PART_ButtonPrePage") as Button;
        if (_btnPrePage != null)
        {
            _btnPrePage.Click += _btnPrePage_Click;
        }

        _btnNextPage = GetTemplateChild("PART_ButtonNextPage") as Button;
        if (_btnNextPage != null)
        {
            _btnNextPage.Click += _btnNextPage_Click;
        }

        _btnLastPage = GetTemplateChild("PART_ButtonLastPage") as Button;
        if (_btnLastPage != null)
        {
            _btnLastPage.Click += _btnLastPage_Click;
        }
    }

    /// <summary>
    /// 初始化数据
    /// </summary>
    private void InitData()
    {
        try
        {
            _isIgnoreListBoxSelectionChanged = true;
            if (PageDataCount > 0)
            {
                //根据总的数据量和每页最大显示的数据量计算总的页数
                if (TotalDataCount % PageDataCount > 0)
                {
                    TotalPageCount = TotalDataCount / PageDataCount + 1;
                }
                else
                {
                    TotalPageCount = TotalDataCount / PageDataCount;
                }

                //将可选择页码加入到数据绑定集合中
                if (ShowingPageNumberCollection != null)
                {
                    lock (_lock)
                    {
                        ShowingPageNumberCollection.Clear();
                        int addPageCount = MaxShownPageCount;
                        if (TotalPageCount < MaxShownPageCount)
                        {
                            addPageCount = TotalPageCount;
                        }

                        for (int i = 1; i <= addPageCount; i++)
                        {
                            ShowingPageNumberCollection.Add(i);
                        }
                    }
                }

                //初始化选中页
                if (_lstShowingPage != null)
                {
                    _lstShowingPage.SelectedIndex = 0;
                    CurrentPageNumber = 1;
                }

                //更新分页数据信息
                UpdateShowingPageInfo();
            }

            SetBtnEnable();
        }
        finally
        {
            _isIgnoreListBoxSelectionChanged = false;
        }
    }

    private void _cbbPageDataCount_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ComboBox cbb = sender as ComboBox;
        if (cbb == null || cbb.SelectedItem == null)
        {
            return;
        }

        string selectedCountString = cbb.SelectedItem.ToString();
        if (!int.TryParse(selectedCountString, out int selectedDataCount))
        {
            return;
        }

        PageDataCount = selectedDataCount;
        InitData();
    }

    private void _lstShowingPage_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (_isIgnoreListBoxSelectionChanged)
        {
            return;
        }

        try
        {
            _isIgnoreListBoxSelectionChanged = true;

            ListBox lst = sender as ListBox;
            if (lst == null || lst.SelectedItem == null)
            {
                return;
            }

            string selectedPageString = lst.SelectedItem.ToString();
            if (!int.TryParse(selectedPageString, out int selectedPageNumber))
            {
                return;
            }

            //总页数小于最大可显示页数表明无论选中的页数为何，均不需要改动页码集合中的数据，此时直接返回
            if (TotalPageCount <= MaxShownPageCount)
            {
                CurrentPageNumber = selectedPageNumber;
                UpdateShowingPageInfo();
                return;
            }

            //计算为保持选中项居中而需要向右移动的次数 比较中间位置与选中项的下标
            int moveCount = MaxShownPageCount / 2 - _lstShowingPage.SelectedIndex;
            int startPageNumber = ShowingPageNumberCollection.First();
            if (moveCount > 0) //向右移动
            {
                int realMoveCount = moveCount;
                if (ShowingPageNumberCollection.First() - 1 < moveCount)
                {
                    realMoveCount = ShowingPageNumberCollection.First() - 1;
                }

                startPageNumber = ShowingPageNumberCollection.First() - realMoveCount;
            }
            else if (moveCount < 0) //向左移动
            {
                int realMoveCount = -moveCount;
                if (TotalPageCount - ShowingPageNumberCollection.Last() < realMoveCount)
                {
                    realMoveCount = TotalPageCount - ShowingPageNumberCollection.Last();
                }

                startPageNumber = ShowingPageNumberCollection.First() + realMoveCount;
            }

            lock (_lock)
            {
                ShowingPageNumberCollection.Clear();
                for (int i = 0; i < MaxShownPageCount; i++)
                {
                    ShowingPageNumberCollection.Add(startPageNumber + i);
                }
            }

            int selectedItemIndex = ShowingPageNumberCollection.IndexOf(selectedPageNumber);
            _lstShowingPage.SelectedIndex = selectedItemIndex;

            CurrentPageNumber = selectedPageNumber;
            UpdateShowingPageInfo();
        }
        finally
        {
            _isIgnoreListBoxSelectionChanged = false;
        }
    }

    /// <summary>
    /// 跳转到首页
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void _btnFirstPage_Click(object sender, RoutedEventArgs e)
    {
        if (_lstShowingPage == null
            || ShowingPageNumberCollection == null
            || ShowingPageNumberCollection.Count == 0)
        {
            return;
        }

        if (ShowingPageNumberCollection[0] != 1)
        {
            try
            {
                _isIgnoreListBoxSelectionChanged = true;
                lock (_lock)
                {
                    ShowingPageNumberCollection.Clear();
                    for (int i = 1; i <= MaxShownPageCount; i++)
                    {
                        ShowingPageNumberCollection.Add(i);
                    }
                }
            }
            finally
            {
                _isIgnoreListBoxSelectionChanged = false;
            }
        }

        _lstShowingPage.SelectedIndex = 0;
    }

    /// <summary>
    /// 跳转到尾页
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void _btnLastPage_Click(object sender, RoutedEventArgs e)
    {
        if (_lstShowingPage == null
          || ShowingPageNumberCollection == null
          || ShowingPageNumberCollection.Count == 0)
        {
            return;
        }

        if (ShowingPageNumberCollection.Last() != TotalPageCount)
        {
            try
            {
                _isIgnoreListBoxSelectionChanged = true;
                lock (_lock)
                {
                    ShowingPageNumberCollection.Clear();
                    for (int i = 0; i < MaxShownPageCount; i++)
                    {
                        ShowingPageNumberCollection.Add(TotalPageCount - MaxShownPageCount + i + 1);
                    }
                }
            }
            finally
            {
                _isIgnoreListBoxSelectionChanged = false;
            }
        }

        _lstShowingPage.SelectedIndex = _lstShowingPage.Items.Count - 1;
    }

    /// <summary>
    /// 跳转到前一页
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void _btnPrePage_Click(object sender, RoutedEventArgs e)
    {
        if (_lstShowingPage == null
            || ShowingPageNumberCollection == null
            || ShowingPageNumberCollection.Count == 0)
        {
            return;
        }

        if (_lstShowingPage.SelectedIndex > 0)
        {
            _lstShowingPage.SelectedIndex--;
        }
    }

    /// <summary>
    /// 跳转到后一条
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void _btnNextPage_Click(object sender, RoutedEventArgs e)
    {
        if (_lstShowingPage == null
            || ShowingPageNumberCollection == null
            || ShowingPageNumberCollection.Count == 0)
        {
            return;
        }

        if (_lstShowingPage.SelectedIndex < MaxShownPageCount - 1)
        {
            _lstShowingPage.SelectedIndex++;
        }
    }

    private void UpdateShowingPageInfo()
    {
        if (TotalPageCount == 0)
        {
            ShowingPageDataStartNumber = 0;
            ShowingPageDataEndNumber = 0;
        }
        else if (CurrentPageNumber < TotalPageCount)
        {
            ShowingPageDataStartNumber = (CurrentPageNumber - 1) * PageDataCount + 1;
            ShowingPageDataEndNumber = CurrentPageNumber * PageDataCount;
        }
        else if (CurrentPageNumber == TotalPageCount)
        {
            ShowingPageDataStartNumber = (CurrentPageNumber - 1) * PageDataCount + 1;
            ShowingPageDataEndNumber = TotalDataCount;
        }
    }

    /// <summary>
    /// 设置按钮的可用性
    /// </summary>
    private void SetBtnEnable()
    {
        if (_btnFirstPage == null || _btnPrePage == null
            || _btnNextPage == null || _btnLastPage == null)
        {
            return;
        }

        _btnPrePage.IsEnabled = true;
        _btnNextPage.IsEnabled = true;
        _btnFirstPage.IsEnabled = true;
        _btnLastPage.IsEnabled = true;

        if (ShowingPageNumberCollection == null || ShowingPageNumberCollection.Count == 0)//集合为空或者无数据，则所有按钮不可用
        {
            _btnPrePage.IsEnabled = false;
            _btnNextPage.IsEnabled = false;
            _btnFirstPage.IsEnabled = false;
            _btnLastPage.IsEnabled = false;
        }
        else
        {
            if (CurrentPageNumber == 1)
            {
                _btnFirstPage.IsEnabled = false;
                _btnPrePage.IsEnabled = false;
            }

            if (CurrentPageNumber == TotalPageCount)
            {
                _btnNextPage.IsEnabled = false;
                _btnLastPage.IsEnabled = false;
            }
        }
    }
}